package com.nebula.core.dsl;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;

import java.util.List;

/**
 * @author zhangtao
 */
public class NebulaOutputVisitor extends MySqlOutputVisitor {

    public NebulaOutputVisitor(Appendable appender) {
        super(appender);
    }

    @Override
    public void printOperator(SQLBinaryOperator operator) {
        if (operator.equals(SQLBinaryOperator.Equality)) {
            print0("==");
        } else {
            print0(ucase ? operator.name : operator.name_lcase);
        }
    }

    @Override
    public boolean visit(SQLInListExpr x) {
        final SQLExpr expr = x.getExpr();

        boolean quote = false;
        if (expr instanceof SQLBinaryOpExpr) {
            SQLBinaryOperator operator = ((SQLBinaryOpExpr) expr).getOperator();
            switch (operator) {
                case BooleanAnd:
                case BooleanOr:
                case BooleanXor:
                case Assignment:
                    quote = true;
                    break;
                default:
                    quote = ((SQLBinaryOpExpr) expr).isBracket();
                    break;
            }
        } else if (expr instanceof SQLNotExpr
                || expr instanceof SQLBetweenExpr
                || expr instanceof SQLInListExpr
                || expr instanceof SQLUnaryExpr
                || expr instanceof SQLBinaryOpExprGroup) {
            quote = true;
        }

        if (quote) {
            print('(');
        }
        printExpr(expr, parameterized);
        if (quote) {
            print(')');
        }

        if (x.isNot()) {
            print0(ucase ? " NOT IN [" : " not in [");
        } else {
            print0(ucase ? " IN [" : " in [");
        }

        List<SQLExpr> targetList = x.getTargetList();
        for (int i = 0; i < targetList.size(); i++) {
            if (i != 0) {
                print0(", ");
            }
            printExpr(targetList.get(i), parameterized);
        }

        print(']');

        return false;
    }

}
